package com.fand.platform.configuration.service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.fand.dto.PaginationDto;
import com.fand.platform.configuration.dao.LanguageDao;
import com.fand.platform.configuration.dto.DictionaryDto;
import com.fand.platform.configuration.dto.LanguageDto;

/**
 * 语言服务
 * 
 * @author yaoHT
 * 
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class LanguageDefaultService implements LanguageService {
	private LanguageDao languageDao;

	private ConfigurationService configurationService;

	@Override
	@Transactional
	public int deleteLanguageBy1(LanguageDto deleteLanguage) {
		return this.languageDao.deleteLanguageBy1(deleteLanguage, new String[] {});
	}

	@Override
	@Transactional
	public int deleteLanguageByIds(LanguageDto deleteLanguage) {
		return this.languageDao.deleteLanguageByIds(deleteLanguage);
	}

	@Override
	public List<LanguageDto> findLanguageBy1(LanguageDto findLanguage) {
		return this.languageDao.selectLanguageBy1ForMappedObjectList(LanguageDto.class, findLanguage,
				new String[] {}, new String[] {});
	}

	@Override
	public List<LanguageDto> findLanguageBy2(LanguageDto findLanguage) {
		return this.languageDao.selectLanguageBy2ForMappedObjectList(LanguageDto.class, findLanguage);
	}

	@Override
	public LanguageDto getLanguageBy1(LanguageDto getLanguage) {
		return this.languageDao.selectLanguageBy1ForMappedObject(LanguageDto.class, getLanguage, new String[] {},
				new String[] {});
	}

	@Override
	public LanguageDto getLanguageById(LanguageDto getLanguage) {
		LanguageDto language = this.languageDao.selectLanguageByIdForMappedObject(LanguageDto.class, getLanguage);

		if (language == null) {
			return null;
		}

		List<LanguageDto> languageList = this.languageDao.selectLanguageByCodeForMappedObjectList(LanguageDto.class,
				language);

		if (CollectionUtils.isEmpty(languageList)) {
			return language;
		}

		for (LanguageDto itemLanguage : languageList) {
			language.getContentMap().put(itemLanguage.getLocaleCo(), itemLanguage.getContent());
		}

		return language;
	}

	@Override
	public PaginationDto<LanguageDto> paginationLanguageBy1ForLanguageList(LanguageDto paginationLanguage) {
		return this.languageDao.paginationLanguageBy1ForMappedObjectList(LanguageDto.class, paginationLanguage);
	}

	@Override
	public PaginationDto<Map<String, Object>> paginationLanguageBy1ForMapList(LanguageDto paginationLanguage) {
		return this.languageDao.paginationLanguageBy1ForMapList(paginationLanguage);
	}

	@Override
	public Integer readLanguageBy2ForInteger(LanguageDto readLanguage) {
		return this.languageDao.selectLanguageBy2ForObject(Integer.class, readLanguage, null);
	}

	@Override
	public Integer readLanguageByCodeNqIdForInteger(LanguageDto readLanguage) {
		LanguageDto language = null;

		if (StringUtils.isNotBlank(readLanguage.getId())) {
			language = this.languageDao
					.selectLanguageBy1ForMappedObject(LanguageDto.class, readLanguage, null, "id");

			if (language != null) {
				language.setCode(readLanguage.getCode());

				return this.languageDao.selectLanguageByLocaleIdEqCodeNqIdForInteger(language);
			}
		}

		List<DictionaryDto> dictionaryList = this.configurationService.getDictionaryService()
				.findDictionaryByTypeCo("LOCALE");

		if (CollectionUtils.isEmpty(dictionaryList)) {
			return 0;
		}

		for (DictionaryDto dictionary : dictionaryList) {
			language = new LanguageDto();

			language.setId(readLanguage.getId());
			language.setLocaleId(dictionary.getId());
			language.setCode(readLanguage.getCode());

			int count = this.languageDao.selectLanguageByLocaleIdEqCodeNqIdForInteger(language);

			if (count > 0) {
				return count;
			}
		}

		return 0;
	}

	@Override
	public List<Integer> readListLanguageBy1(LanguageDto readLanguage) {
		return this.languageDao.selectLanguageBy1ForObjectList(Integer.class, readLanguage, null, new String[] {});
	}

	@Override
	public List<Integer> readListLanguageBy2(LanguageDto readLanguage) {
		return this.languageDao.selectLanguageBy2ForObjectList(Integer.class, readLanguage, null);
	}

	@Override
	@CacheEvict(value = LanguageService.CACHE_NAME, allEntries = true)
	public void reload() {
	}

	@Override
	@Transactional
	public LanguageDto saveLanguageBy2ForLanguage(LanguageDto saveLanguage) {
		LanguageDto oldLanguage = this.languageDao.selectLanguageBy1ForMappedObject(LanguageDto.class, saveLanguage,
				new String[] {}, new String[] {});

		if (oldLanguage == null) {
			this.languageDao.insertLanguageBy1(saveLanguage, new String[] {});

			return saveLanguage;
		}

		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveLanguage, oldLanguage);

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.languageDao.updateLanguageBy1(saveLanguage, updateProperties, new String[] {});
		}

		return saveLanguage;
	}

	@Override
	@Transactional
	public LanguageDto saveLanguageByIdOrCodeForLanguage(LanguageDto saveLanguage) {
		List<DictionaryDto> dictionaryList = this.configurationService.getDictionaryService()
				.findDictionaryByTypeCo("LOCALE");

		if (CollectionUtils.isEmpty(dictionaryList)) {
			return saveLanguage;
		}

		String[] whereEqProperties;

		String oldCode = null;

		if (StringUtils.isNotBlank(saveLanguage.getId())) {
			whereEqProperties = new String[] { "id" };

			LanguageDto oldLanguage = this.languageDao.selectLanguageBy1ForMappedObject(LanguageDto.class,
					saveLanguage, null, whereEqProperties);

			if (oldLanguage != null) {
				oldCode = oldLanguage.getCode();
			}
		}

		for (DictionaryDto dictionary : dictionaryList) {
			LanguageDto selectLanguage = new LanguageDto();

			selectLanguage.setLocaleId(dictionary.getId());
			selectLanguage.setCode(StringUtils.defaultString(oldCode, saveLanguage.getCode()));

			whereEqProperties = new String[] { "localeId", "code" };

			LanguageDto oldLanguage = this.languageDao.selectLanguageBy1ForMappedObject(LanguageDto.class,
					selectLanguage, null, whereEqProperties);

			saveLanguage.setLocaleId(dictionary.getId());
			saveLanguage.setContent((String) saveLanguage.getContentMap().get(dictionary.getCode()));

			if (oldLanguage == null) {
				saveLanguage.setId(UUID.randomUUID().toString());
				saveLanguage.setBeginDaTi(new Date());
				saveLanguage.setEndDaTi(new DateTime(9999, 12, 31, 0, 0, 0, 0).toDate());

				this.languageDao.insertLanguageBy1(saveLanguage);

				continue;
			}

			String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveLanguage, oldLanguage, "code",
					"content");

			if (ArrayUtils.isNotEmpty(updateProperties)) {
				this.languageDao.updateLanguageByLocaleIdEqCode(saveLanguage, updateProperties, selectLanguage);

				com.fand.utils.BeanUtils.copyProperties(saveLanguage, oldLanguage, updateProperties);
			}
		}

		return saveLanguage;
	}

	@Override
	@Transactional
	public int setLanguageBy1(LanguageDto setLanguage) {
		return this.languageDao.updateLanguageBy1(setLanguage, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	public int setLanguageBy2(LanguageDto setLanguage) {
		return this.languageDao.updateLanguageBy2(setLanguage);
	}
}